ProForm

ProForm adds some syntactic sugar and more layout settings to the original Form to help us develop a form quickly. Also add some default behaviors to make our forms work well by default.

Step-by-step forms, Modal forms, Drawer forms, Query forms, Lightweight filters and many other layouts can cover most of the usage scenarios and get rid of the complicated and tedious form layout work and do more with less code.

  • If you want to set default values, please use initialValues, any direct use of component value and onChange may cause value binding failure.

  • If you want to link forms or do some dependencies, you can use render props mode, ProFormDependency is definitely the best choice

  • ProForm's onFinish, unlike antd's Form, is a Promise that will automatically set the button to load for you if you return normally.

  • If you want to listen to a value, it is recommended to use onValuesChange. Keeping a unidirectional data flow is a great benefit for both developers and maintainers

  • ProForm has no black technology, it's just a wrapper for antd's Form, if you want to use a custom component you can wrap it with Form.

// Set overall default values
<ProForm initialValues={obj} />
// Set the individual control's
<ProForm
onValuesChange={(changeValues) => console.log(changeValues)}
>
<ProFormText initialValue="prop"/>
</ProForm>.
// Interdependent component linkage
<ProForm
<ProForm.Item noStyle shouldUpdate>
{(form) => {
return (
<ProFormSelect
options={[
{
value: "chapter",
label: "Effective when stamped",
},
]}
width="md"
name="useMode"
label={`with${form.getFieldValue("name")}contract agreement effective mode`}
/>
);
}}
</ProForm.Item>.
</ProForm>;
// Using custom components
<ProForm
<ProForm.Item name="switch" label="Switch" valuePropName="checked">
<Switch />
</ProForm.Item
</ProForm

Data conversion

Many times there is no exact match between the data required by the component and the data required by the backend, and ProForm provides two APIs to solve this problem, 'transform' and 'convertValue'.

convertValue Pre-conversion

convertValue occurs before the component obtains data, usually the data directly sent from the backend to the frontend, and sometimes needs to be refined.

export type SearchConvertKeyFn = (value: any, field: NamePath) => string | Record<string, any>;
/**
* @name Converts the value when getting it, generally used to format the data into the format received by the component
* @param value field value
* @param namePath field name
* @returns the new value of the field
*
*
* @example a,b => [a,b] convertValue: (value,namePath)=> value.split(",")
* @example string => json convertValue: (value,namePath)=> JSON.parse(value)
* @example number => date convertValue: (value,namePath)=> Moment(value)
* @example YYYY-MM-DD => date convertValue: (value,namePath)=> Moment(value,"YYYY-MM-DD")
* @example string => object convertValue: (value,namePath)=> { return {value,label:value} }
*/
convertValue?: SearchConvertKeyFn;

transform transform when submitting

Transform occurs when submitting, generally speaking, it is spit out the data stored in the database to the backend.

For the convenience of everyone, both ProFormDependency and formRef support transform, which can get the transformed value.

<ProFormDependency>
{(value, form) => {
// value is transformed by transform
// form's current formRef, you can get the unconverted value
return ReactNode;
}}
</ProFormDependency>

formRef has several built-in methods to get the converted value, which is also more functional than antd's Form. For details, see the type definition of ProFormInstance.

/** Get all data formatted by ProForm */
getFieldsFormatValue?: (nameList?: true) => T;
/** Get the single data after formatting */
getFieldFormatValue?: (nameList?: NamePath) => T;
/** Get the single data after formatting */
getFieldFormatValueObject?: (nameList?: NamePath) => T;
/** After validating the fields, return all the data after formatting */
validateFieldsReturnFormatValue?: (nameList?: NamePath[]) => Promise<T>;
export type SearchTransformKeyFn = (
value: any,
namePath: string,
allValues: any,
) => string | Record<string, any>;
/**
* @name Convert value when submitting, generally used to convert value into submitted data
* @param value field value
* @param namePath field name
* @param allValues ​​all fields
* The new value of the @returns field, if an object is returned, it will be merged with all values ​​once
*
* @example {name:[a,b] => {name:a,b } transform: (value,namePath,allValues)=> value.join(",")
* @example {name: string => { newName:string } transform: (value,namePath,allValues)=> { newName:value }
* @example {name:moment} => {name:string transform: (value,namePath,allValues)=> value.format("YYYY-MM-DD")
* @example {name:moment}=> {name:timestamp} transform: (value,namePath,allValues)=> value.valueOf()
* @example {name:{value,label}} => { name:string} transform: (value,namePath,allValues)=> value.value
* @example {name:{value,label}} => { valueName,labelName } transform: (value,namePath,allValues)=> { valueName:value.value, labelName:value.name }
*/
transform?: SearchTransformKeyFn;

When to Use

ProForm is the best choice when you want to implement a form quickly but don't want to spend too much time on layout.

Code examples

Basic Usage

Grid mode

supported in ProForm, SchemaForm, ModalForm, DrawerForm, StepsForm

Form's layout toggle

盖章后生效
请选择

Interdependent form entries

盖章后生效
盖章后生效

Sync submission results to url

盖章后生效

Money

Form linkage

策略一
策略二

Layouts API

ProForm

ProForm is a repackaging of antd Form, if you want to customize form elements, ProForm is the same way as antd, you can still customize it with FormItem + custom components. Of course this does not affect other components, QueryFilter and other components as well.

antd's Form api View here

ParametersDescriptionTypeDefault
onFinishCallback event after form is submitted and data validation is successful, same as antd 4 Form component API(values)=>Promise<void>-
onResetCallback for clicking the reset button(e)=>void-
submitterSubmitter button-related configurationboolean | SubmitterPropstrue
dateFormatterAutoFormat data, mainly moment forms, supports string and number modes. you also can use formatter function to format datestring| number | ((value: Moment, valueType: string) => string | number) |falsestring
syncToUrlsync parameters to url,url only supports string, better read documentation before usingtrue | (values,type)=>values-
omitNilProForm automatically clears null and undefined data, if you have agreed that nil means something, set to false to disable this featurebooleantrue
formRefGet the form used by the formReact.MutableRefObject<ProFormInstance<T>>-
paramsParameters for initiating network requests, used in conjunction with requestRecord-
requestThe parameters of the initiating network request, the return value will be overwritten to initialValues(params)=>Promise<data>-
isKeyPressSubmitWhether to use carriage return to submitboolean-
autoFocusFirstInputThe first input box of the auto focus formboolean-
gridEnable grid mode, default width 100%, use colProps to control widthboolean-
rowPropsPassed to Row when grid mode is enabledRowProps{ gutter: 8 }
string(...)support other antd Form component parameters besides wrapperCol | labelCol | layout-

ProFormInstance

ProFormInstance adds some capabilities compared to antd's form.

/**
* Get all data formatted by ProForm
* @param nameList boolean
* @returns T
*
* @example getFieldsFormatValue() -> returns all data
* @example getFieldsFormatValue(true) -> returns all data, even if not hosted by form
*/
getFieldsFormatValue?: (nameList?: true) => T;
/**
* Get a single data formatted by ProForm
* @param nameList (string|number)[]
* @returns T
*
* @example {a:{b:value}} -> getFieldFormatValue(['a', 'b']) -> value
*/
/** Get the single data after formatting */
getFieldFormatValue?: (nameList?: NamePath) => T;
/**
* Get the single data formatted by ProForm, including his name
* @param nameList (string|number)[]
* @returns T
*
* @example {a:{b:value}} -> getFieldFormatValueObject(['a', 'b']) -> {a:{b:value}}
*/
/** Get the single data after formatting */
getFieldFormatValueObject?: (nameList?: NamePath) => T;
/**
*Return all data after formatting after field validation
* @param nameList (string|number)[]
* @returns T
*
* @example validateFieldsReturnFormatValue -> {a:{b:value}}
*/
validateFieldsReturnFormatValue?: (nameList?: NamePath[]) => Promise<T>;

ProForm.Group

ParametersDescriptionTypeDefault
titletitlestring-
childrenform control or other elementReact.ReactNode-

submitter

While we would prefer not to modify the submitter, it is a common requirement to do so in use, and ProForm's components use the same API to support the requirement.

ParametersDescriptionTypeDefault
onSubmitSubmit method()=>void-
onResetReset method()=>void-
searchConfigThe configuration of the search, generally used to configure the text{resetText,submitText}-
submitButtonPropsThe props for the submit buttonButtonProps-
resetButtonPropsThe props for the reset buttonButtonProps-
renderRendering of custom actionsfalse |(props,dom:JSX[])=>ReactNode[]-

The second argument to > render is the default dom array, the first is the reset button and the second is the submit button.

<ProForm
submitter={{
// Configure the button text
searchConfig: {
resetText: 'reset',
submitText: 'submit',
},
// Configure the properties of the button
resetButtonProps: {
style: {
// Hide the reset button
display: 'none',
},
},
submitButtonProps: {},
// Fully customize the entire area
render: (props, doms) => {
console.log(props);
return [
<button type="button" key="rest" onClick={() => props.form?.resetFields()}>
Reset
</button>,
<button type="button" key="submit" onClick={() => props.form?.submit?.()}>
Submit
</button>,
];
},
}}
/>